interface _CU_ {
    /**
     * 克隆对象
     * @param obj 对象
     * @returns 新对象
     */
    clone: <T>(obj: T) => T;
}
{
    const cloneObj = (result: any, obj: any, cache: any) => {
        if (cache.has(obj)) { return cache.get(obj); }// 有缓存时直接返回缓存值
        cache.set(obj, result);// 缓存
        for (const key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key)) {
                result[key] = clone(obj[key], cache);
            }
        }
        return result;
    };

    const clone = U.F.overloading('Utils-clone-clone',
        {
            // 对象
            types: [Etype.obj, Etype.WeakMap],
            fn: (obj: any, cache: any) => {
                return cloneObj({}, obj, cache);
            },
        },
        {
            // 数组
            types: [Etype.array, Etype.WeakMap],
            fn: (obj: any, cache: any) => {
                return cloneObj([], obj, cache);
            },
        },
        {
            // Map
            types: [Etype.Map, Etype.WeakMap],
            fn: (obj: Map<any, any>, cache: any) => {
                if (cache.has(obj)) { return cache.get(obj); }// 有缓存时直接返回缓存值
                const result = new Map();
                cache.set(obj, result);// 缓存
                for (const [key, value] of obj) {
                    result.set(key, clone(obj.get(key), cache));
                }
                return result;
            },
        },
        {
            // Set
            types: [Etype.Set, Etype.WeakMap],
            fn: (obj: Set<any>, cache: any) => {
                if (cache.has(obj)) { return cache.get(obj); }// 有缓存时直接返回缓存值
                const result = new Set();
                cache.set(obj, result);// 缓存
                for (const value of obj) {
                    result.add(clone(value, cache));
                }
                return result;
            },
        },
        {
            // 空对象
            types: [Etype.NULLOBJ, Etype.WeakMap],
            fn: U.F.fn.nullObj
        },
        {
            // 其它
            types: [U.F.argType.any, Etype.WeakMap],
            fn: U.F.fn.obj
        }
    );

    _CU_.prototype.clone = U.F.overloading('Utils-clone',
        {
            // 无参
            types: [],
            fn: U.F.fn.emptyObj
        },
        {
            // 数组 对象 集合
            types: [U.F.argType.nest],
            fn: (obj: any) => { return clone(obj, new WeakMap()); }
        },
        {
            // 空对象
            types: [Etype.NULLOBJ],
            fn: U.F.fn.nullObj
        },
        {
            // 其它
            types: [U.F.argType.any],
            fn: U.F.fn.obj
        }
    );
}
